﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using LitJson;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using static DMC300Axis_IO.Function.DMC300_Info;
using System.Runtime.InteropServices.ComTypes;
using MvCameraControl;
using OCR.Config;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using OCR.SettingsForm;

namespace OCR.Algorithm
{
    class AlgorithmModule_CPU
    {
        //-cpu_ocr
        [DllImport(@"-cpu_ocr.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void CreateInstance();
        [DllImport(@"-cpu_ocr.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr do_ocr(byte[] imageData, int width, int height);
        [DllImport(@"-cpu_ocr.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void DestroyInstance();

        public static List<List<Point>> pointsList = new List<List<Point>>();
        public static List<List<Point>> convertList = new List<List<Point>>();

        public static List<TemplateConfig> currConfigs = new List<TemplateConfig>();
        public static Image ImageHandleV2(Image img)
        {
            Console.WriteLine("pixel: "+img.PixelFormat);
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            System.Drawing.Bitmap bitmap = new Bitmap(img);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            //Console.WriteLine(imageData.Length);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;


            return bitmap;
        }
        public static Image ImageHandleV2(string path)
        {
            pointsList.Clear();
            // 读取本地图片
            //string imagePath = "G:\\yyx\\3588test\\ocr\\0727\\Image_20240726151820440.bmp"; // 替换图片路径
            System.Drawing.Bitmap bitmap = new Bitmap(path);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            //Console.WriteLine(imageData.Length);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0], configs[i].box[j][1]);
                    Console.WriteLine("X: " + point.X+"  "+ "Y: " + point.Y);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;

            return bitmap;
        }
        public static Image ImageHandleV2_Scale4_Local(string path, string outpath, int scale)
        {
            pointsList.Clear();
            //// 读取本地图片
            System.Drawing.Bitmap bitmap = new Bitmap(path);

            ////Bitmap bitmap = ResizeImage(path, outpath);
            //// 获取图片数据
            //Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            //BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            //int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            //byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            //// 拷贝数据
            //System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            //bitmap.UnlockBits(bmpData);
            //IntPtr resultPtr = do_ocr(imageData, bitmap.Width, bitmap.Height);

            //byte[] imageData = SafeScaleLocalImageZoomOut(path, scale);
            byte[] imageData = SafeScaleBitmapImageZoomOut(bitmap, scale);
            IntPtr resultPtr = do_ocr(imageData, bitmap.Width / scale, bitmap.Height / scale);

            //byte[] imageData = CompressImage(path, outpath, 100);
            ////byte[] imageData = CompressImage1(path,100);
            //IntPtr resultPtr = do_ocr(imageData, bitmap.Width, bitmap.Height);

            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0] * scale, configs[i].box[j][1] * scale);
                    //Console.WriteLine(point.X+"  "+point.Y);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;

            convertList = ConvertPointList(pointsList, new Rectangle(x: 218, y: 530, width: 748, height: 310));

            return bitmap;
        }
        public static Image ImageHandleV2_Scale4_Local(Bitmap bitmap, string outpath, int scale)
        {
            pointsList.Clear();
            //// 读取本地图片
            //System.Drawing.Bitmap bitmap = new Bitmap(path);

            ////Bitmap bitmap = ResizeImage(path, outpath);
            //// 获取图片数据
            //Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            //BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            //int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            //byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            //// 拷贝数据
            //System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            //bitmap.UnlockBits(bmpData);
            //IntPtr resultPtr = do_ocr(imageData, bitmap.Width, bitmap.Height);

            byte[] imageData = SafeScaleBitmapImageZoomOut(bitmap, scale);
            IntPtr resultPtr = do_ocr(imageData, bitmap.Width / scale, bitmap.Height / scale);

            //byte[] imageData = CompressImage(path, outpath, 100);
            ////byte[] imageData = CompressImage1(path,100);
            //IntPtr resultPtr = do_ocr(imageData, bitmap.Width, bitmap.Height);

            string result = Marshal.PtrToStringAnsi(resultPtr);

            byte[] rebytes = Encoding.Default.GetBytes(result);
            result = Encoding.UTF8.GetString(rebytes).Replace("end", "");

            //byte[] rebytes = Encoding.Default.GetBytes(result);
            //byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.Default, rebytes, 0, rebytes.Length);
            //result = Encoding.Default.GetString(bytes, 0, bytes.Length).Replace("end", "");

            Console.WriteLine("OCR Result:\n" + result);

            List<TemplateConfig> configs = new List<TemplateConfig>();
            configs = JsonMapper.ToObject<List<TemplateConfig>>(result);

            for (int i = 0; i < configs.Count; i++)
            {
                Console.WriteLine("算法图片信息" + i + ": " + configs[i].text);
                List<Point> points = new List<Point>();
                for (int j = 0; j < configs[i].box.Count; j++)
                {
                    Point point = new Point(configs[i].box[j][0] * scale, configs[i].box[j][1] * scale);
                    //Console.WriteLine(point.X+"  "+point.Y);
                    points.Add(point);
                }
                pointsList.Add(points);
            }
            currConfigs = configs;

            convertList = ConvertPointList(pointsList, new Rectangle(x: 218, y: 530, width: 748, height: 310));

            return bitmap;
        }
        public static Image RectPoints(Image bitmapInput)
        {
            Bitmap bitmap = new Bitmap(bitmapInput);

            Graphics graphics1 = Graphics.FromImage(bitmap);

            Pen pen = new Pen(Color.Green, 5);

            foreach (var item in pointsList)
            {
                graphics1.DrawLines(pen, item.ToArray());
                graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
            }

            graphics1.Dispose();

            return bitmap;
        }
        public static Image RectPoints(Image bitmapInput,List<List<Point>> pointsList)
        {
            Bitmap bitmap = new Bitmap(bitmapInput);

            Graphics graphics1 = Graphics.FromImage(bitmap);

            Pen pen = new Pen(Color.Green, 5);

            foreach (var item in pointsList)
            {
                graphics1.DrawLines(pen, item.ToArray());
                graphics1.DrawLine(pen, item.ToArray()[0], item.ToArray()[3]);
            }

            graphics1.Dispose();
            DateTime imgDateTime = DateTime.Now;
            Console.WriteLine("triggerDataTime：{0} -imageDateTime：{1} -timeSpan：{2} ", TestScaleForm.triggerDataTime.TimeOfDay, imgDateTime.TimeOfDay, (imgDateTime - TestScaleForm.triggerDataTime).Milliseconds);
            return bitmap;
        }

        private static byte[] SafeScaleLocalImageZoomOut(string path, int scale)
        {
            // 1. 加载源图像
            Bitmap srcBmp = new Bitmap(path);
            int channels = Image.GetPixelFormatSize(srcBmp.PixelFormat) / 8;

            // 2. 创建目标图像（示例缩放为50%）
            int newWidth = srcBmp.Width / scale;
            int newHeight = srcBmp.Height / scale;
            Bitmap dstBmp = new Bitmap(newWidth, newHeight, srcBmp.PixelFormat);

            // 3. 获取像素数据
            var srcData = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height),
                ImageLockMode.ReadOnly, srcBmp.PixelFormat);
            var dstData = dstBmp.LockBits(new Rectangle(0, 0, newWidth, newHeight),
                ImageLockMode.WriteOnly, dstBmp.PixelFormat);

            // 4. 创建托管缓冲区
            byte[] srcBuffer = new byte[srcData.Stride * srcBmp.Height];
            byte[] dstBuffer = new byte[dstData.Stride * newHeight];
            Marshal.Copy(srcData.Scan0, srcBuffer, 0, srcBuffer.Length);

            // 5. 执行安全缩放（双线性插值）
            SafeBilinearScale(srcBuffer, dstBuffer,
                srcBmp.Width, srcBmp.Height,
                newWidth, newHeight,
                channels);
            //SharpBilinearScale(srcBuffer, dstBuffer,
            //    srcBmp.Width, srcBmp.Height,
            //    newWidth, newHeight,
            //    channels);
            //BicubicScale(srcBuffer, dstBuffer,
            //    srcBmp.Width, srcBmp.Height,
            //    newWidth, newHeight,
            //    channels);
            // 6. 写回并显示
            //Marshal.Copy(dstBuffer, 0, dstData.Scan0, dstBuffer.Length);
            srcBmp.UnlockBits(srcData);
            dstBmp.UnlockBits(dstData);

            dstBmp.Save("testBmp.bmp");

            return dstBuffer;
            //picResult.Image = dstBmp;
        }

        private static void SafeBilinearScale(byte[] src, byte[] dst,
            int srcWidth, int srcHeight,
            int dstWidth, int dstHeight,
            int channels)
        {
            float xRatio = (float)srcWidth / dstWidth;
            float yRatio = (float)srcHeight / dstHeight;
            int srcStride = srcWidth * channels;

            for (int y = 0; y < dstHeight; y++)
            {
                float srcY = y * yRatio;
                int y0 = (int)srcY;
                int y1 = Math.Min(y0 + 1, srcHeight - 1);
                float wy = srcY - y0;

                for (int x = 0; x < dstWidth; x++)
                {
                    float srcX = x * xRatio;
                    int x0 = (int)srcX;
                    int x1 = Math.Min(x0 + 1, srcWidth - 1);
                    float wx = srcX - x0;

                    // 获取四个相邻像素的索引
                    int i00 = (y0 * srcWidth + x0) * channels;
                    int i01 = (y0 * srcWidth + x1) * channels;
                    int i10 = (y1 * srcWidth + x0) * channels;
                    int i11 = (y1 * srcWidth + x1) * channels;

                    // 计算目标像素索引
                    int dstIndex = (y * dstWidth + x) * channels;

                    for (int c = 0; c < channels; c++)
                    {
                        // 双线性插值计算
                        float v00 = src[i00 + c];
                        float v01 = src[i01 + c];
                        float v10 = src[i10 + c];
                        float v11 = src[i11 + c];

                        float top = v00 * (1 - wx) + v01 * wx;
                        float bottom = v10 * (1 - wx) + v11 * wx;
                        dst[dstIndex + c] = (byte)(top * (1 - wy) + bottom * wy);
                    }
                }
            }
        }
        private static void SharpBilinearScale(byte[] src, byte[] dst,
    int srcWidth, int srcHeight,
    int dstWidth, int dstHeight,
    int channels)
        {
            // 使用中心对齐采样坐标
            float xScale = (float)srcWidth / dstWidth;
            float yScale = (float)srcHeight / dstHeight;
            int srcStride = srcWidth * channels;

            Parallel.For(0, dstHeight, y =>
            {
                // 计算源图Y坐标（中心对齐）
                float srcY = (y + 0.5f) * yScale - 0.5f;
                int y0 = (int)srcY;
                //y0 = Math.Min(y0, 0, srcHeight - 1);
                int y1 = Math.Min(y0 + 1, srcHeight - 1);
                float wy = srcY - y0;

                for (int x = 0; x < dstWidth; x++)
                {
                    // 计算源图X坐标（中心对齐）
                    float srcX = (x + 0.5f) * xScale - 0.5f;
                    int x0 = (int)srcX;
                    //x0 = Math.Clamp(x0, 0, srcWidth - 1);
                    int x1 = Math.Min(x0 + 1, srcWidth - 1);
                    float wx = srcX - x0;

                    // 获取四个采样点
                    int i00 = y0 * srcStride + x0 * channels;
                    int i01 = y0 * srcStride + x1 * channels;
                    int i10 = y1 * srcStride + x0 * channels;
                    int i11 = y1 * srcStride + x1 * channels;

                    int dstIndex = (y * dstWidth + x) * channels;

                    for (int c = 0; c < channels; c++)
                    {
                        // 双线性插值
                        float v00 = src[i00 + c];
                        float v01 = src[i01 + c];
                        float v10 = src[i10 + c];
                        float v11 = src[i11 + c];

                        float top = v00 * (1 - wx) + v01 * wx;
                        float bottom = v10 * (1 - wx) + v11 * wx;
                        float value = top * (1 - wy) + bottom * wy;

                        // 边缘增强（简化版非锐化掩蔽）
                        float gradient = Math.Abs(v00 - v11) + Math.Abs(v01 - v10);
                        float sharpen = gradient > 30 ? 1.15f : 1.0f; // 动态锐化系数
                        value = Math.Min(value * sharpen, 255);

                        dst[dstIndex + c] = (byte)value;

                    }
                }
            });
        }

        private const float B = 0.0f; // Catmull-Rom 参数
        private const float C = 0.5f;

        public static void BicubicScale(byte[] src, byte[] dst,
            int srcWidth, int srcHeight,
            int dstWidth, int dstHeight,
            int channels)
        {
            float xScale = (float)srcWidth / dstWidth;
            float yScale = (float)srcHeight / dstHeight;
            int srcStride = srcWidth * channels;

            Parallel.For(0, dstHeight, y =>
            {
                float srcY = (y + 0.5f) * yScale - 0.5f;
                int y0 = (int)Math.Floor(srcY);
                y0 = Clamp(y0, 0, srcHeight - 1);
                float dy = srcY - y0;

                for (int x = 0; x < dstWidth; x++)
                {
                    float srcX = (x + 0.5f) * xScale - 0.5f;
                    int x0 = (int)Math.Floor(srcX);
                    x0 = Clamp(x0, 0, srcWidth - 1);
                    float dx = srcX - x0;

                    int dstIndex = (y * dstWidth + x) * channels;

                    for (int c = 0; c < channels; c++)
                    {
                        float sum = 0;
                        for (int m = -1; m <= 2; m++) // y方向四邻域
                        {
                            int yy = Clamp(y0 + m, 0, srcHeight - 1);
                            float wy = CubicWeight(dy - m);

                            for (int n = -1; n <= 2; n++) // x方向四邻域
                            {
                                int xx = Clamp(x0 + n, 0, srcWidth - 1);
                                float wx = CubicWeight(dx - n);

                                int srcIndex = yy * srcStride + xx * channels;
                                sum += src[srcIndex + c] * wx * wy;
                            }
                        }
                        dst[dstIndex + c] = (byte)Math.Max(0, Math.Min(sum, 255));
                    }
                }
            });
        }

        private static float CubicWeight(float t)
        {
            float absT = Math.Abs(t);
            if (absT < 1)
            {
                return (12 - 9 * B - 6 * C) * absT * absT * absT
                     + (-18 + 12 * B + 6 * C) * absT * absT
                     + (6 - 2 * B);
            }
            else if (absT < 2)
            {
                return (-B - 6 * C) * absT * absT * absT
                     + (6 * B + 30 * C) * absT * absT
                     + (-12 * B - 48 * C) * absT
                     + (8 * B + 24 * C);
            }
            return 0;
        }

        private static int Clamp(int value, int min, int max)
        {
            return (value < min) ? min : (value > max) ? max : value;
        }
        private static byte[] SafeScaleBitmapImageZoomOut(Bitmap srcBmp, int scale)
        {

            // 1. 加载源图像
            //Bitmap srcBmp = new Bitmap(srcBmp1);
            //Bitmap srcBmp = srcBmp1;
            int channels = Image.GetPixelFormatSize(srcBmp.PixelFormat) / 8;
            Console.WriteLine(channels);
            // 2. 创建目标图像（示例缩放为50%）
            int newWidth = srcBmp.Width / scale;
            int newHeight = srcBmp.Height / scale;
            Bitmap dstBmp = new Bitmap(newWidth, newHeight, srcBmp.PixelFormat);

            // 3. 获取像素数据
            var srcData = srcBmp.LockBits(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height),
                ImageLockMode.ReadOnly, srcBmp.PixelFormat);
            var dstData = dstBmp.LockBits(new Rectangle(0, 0, newWidth, newHeight),
                ImageLockMode.WriteOnly, dstBmp.PixelFormat);

            // 4. 创建托管缓冲区
            byte[] srcBuffer = new byte[srcData.Stride * srcBmp.Height];
            byte[] dstBuffer = new byte[dstData.Stride * newHeight];
            Marshal.Copy(srcData.Scan0, srcBuffer, 0, srcBuffer.Length);

            // 5. 执行安全缩放（双线性插值）
            SafeBilinearScale(srcBuffer, dstBuffer,
                srcBmp.Width, srcBmp.Height,
                newWidth, newHeight,
                channels);

            // 6. 写回并显示
            //Marshal.Copy(dstBuffer, 0, dstData.Scan0, dstBuffer.Length);
            srcBmp.UnlockBits(srcData);
            dstBmp.UnlockBits(dstData);

            return dstBuffer;
            //picResult.Image = dstBmp;
        }
        public static void ImageHandleV2_Refresh(string path)
        {
            pointsList.Clear();
            // 读取本地图片
            System.Drawing.Bitmap bitmap = new Bitmap(path);

            // 获取图片数据
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bytesPerPixel = Bitmap.GetPixelFormatSize(bitmap.PixelFormat) / 8;
            byte[] imageData = new byte[bmpData.Stride * bitmap.Height];

            // 拷贝数据
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imageData, 0, imageData.Length);
            bitmap.UnlockBits(bmpData);
            IntPtr resultPtr = do_ocr(imageData, bmpData.Width, bmpData.Height);
            string result = Marshal.PtrToStringAnsi(resultPtr);
        }


        public static byte[] CompressImage(string imagePath, string outPath, long quality)
        {
            using (Image image = Image.FromFile(imagePath))
            using (MemoryStream outputStream = new MemoryStream())
            {
                // 获取JPEG编码器
                ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);

                // 配置质量参数
                EncoderParameters encoderParams = new EncoderParameters(1);
                encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

                // 压缩并保存到内存流
                image.Save(outputStream, jpegEncoder, encoderParams);
                image.Save(outPath, jpegEncoder, encoderParams);
                return outputStream.ToArray();
            }
        }

        public static ImageCodecInfo GetEncoder(ImageFormat format)
        {
            foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
        public static byte[] CompressImage1(string imagePath, long quality = 75L)
        {
            // 读取原始图片字节
            byte[] originalBytes = File.ReadAllBytes(imagePath);

            using (var originalStream = new MemoryStream(originalBytes))
            using (Image image = Image.FromStream(originalStream))
            using (var compressedStream = new MemoryStream())
            {
                // 获取JPEG编码器
                ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);

                // 配置编码参数（设置质量）
                EncoderParameters encoderParams = new EncoderParameters(1);
                encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

                // 保存压缩后的图片到内存流
                image.Save(compressedStream, jpegEncoder, encoderParams);

                // 返回压缩后的字节数组
                return compressedStream.ToArray();
            }
        }

        public static Image CompressImage2(string imagePath, long quality = 100L)
        {
            // 读取原始图片字节
            byte[] originalBytes = File.ReadAllBytes(imagePath);

            using (var originalStream = new MemoryStream(originalBytes))
            using (Image image = Image.FromStream(originalStream))
            using (var compressedStream = new MemoryStream())
            {
                // 获取JPEG编码器
                ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);

                // 配置编码参数（设置质量）
                EncoderParameters encoderParams = new EncoderParameters(1);
                encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

                // 保存压缩后的图片到内存流
                image.Save(compressedStream, jpegEncoder, encoderParams);

                // 返回压缩后的字节数组
                return Image.FromStream(compressedStream);
            }
        }
        public static Image CompressImage2(string imagePath, string outPath, long quality = 100L)
        {
            // 读取原始图片字节
            //byte[] originalBytes = File.ReadAllBytes(imagePath);

            //using (var originalStream = new MemoryStream(originalBytes))
            //using (Image image = Image.FromStream(originalStream))
            var image = new Bitmap(imagePath);

            // 获取JPEG编码器
            ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);

            // 配置编码参数（设置质量）
            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

            // 保存压缩后的图片到内存流
            //image.Save(compressedStream, jpegEncoder, encoderParams);

            // 保存压缩后的图片
            image.Save(outPath, jpegEncoder, encoderParams);

            //ImageHandleV2(outPath);

            Bitmap bitmap = new Bitmap(ImageHandleV2(outPath));
            //ImageHandleV2(outPath);

            // 返回压缩后的字节数组
            return bitmap;
            //using (var compressedStream = new MemoryStream())
            //{

            //}
        }
        public static Image CompressImage2(Image img, string outPath, long quality = 100L)
        {
            // 读取原始图片字节
            //byte[] originalBytes = File.ReadAllBytes(imagePath);

            //using (var originalStream = new MemoryStream(originalBytes))
            //using (Image image = Image.FromStream(originalStream))
            var image = new Bitmap(img);

            // 获取JPEG编码器
            ImageCodecInfo jpegEncoder = GetEncoder(ImageFormat.Jpeg);

            // 配置编码参数（设置质量）
            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

            // 保存压缩后的图片到内存流
            //image.Save(compressedStream, jpegEncoder, encoderParams);

            // 保存压缩后的图片
            image.Save(outPath, jpegEncoder, encoderParams);

            //ImageHandleV2(outPath);

            Bitmap bitmap = new Bitmap(ImageHandleV2(outPath));
            //ImageHandleV2(outPath);

            // 返回压缩后的字节数组
            return bitmap;
            //using (var compressedStream = new MemoryStream())
            //{

            //}
        }

        public static void ResizeImage(string inputPath, string outputPath)
        {
            // 加载原始图片
            using (Image originalImage = Image.FromFile(inputPath))
            {
                // 计算新尺寸（宽高各缩小一半）
                int newWidth = originalImage.Width / 4;
                int newHeight = originalImage.Height / 4;

                // 创建目标位图
                using (Bitmap resizedImage = new Bitmap(newWidth, newHeight))
                {
                    // 使用高质量设置进行绘制
                    using (Graphics graphics = Graphics.FromImage(resizedImage))
                    {
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;

                        // 绘制缩放后的图像
                        graphics.DrawImage(originalImage,
                            new Rectangle(0, 0, newWidth, newHeight),
                            new Rectangle(0, 0, originalImage.Width, originalImage.Height),
                            GraphicsUnit.Pixel);
                    }
                    //Bitmap bitmap = resizedImage.Clone(new Rectangle(0, 0, resizedImage.Width, resizedImage.Height), originalImage.PixelFormat);
                    Bitmap bitmap = ConvertTo8bpp(resizedImage);
                    ImageHandleV2(bitmap);
                    bitmap.Save("pixtestx4.bmp");

                    // 保存结果（保持原始格式）
                    //ImageFormat format = GetImageFormat(inputPath);
                    resizedImage.Save(outputPath);
                    //Console.WriteLine(resizedImage.Size);
                    //return resizedImage;
                }
            }
        }

        public static void ResizeImage(string inputPath, string outputPath, int scaleFactor)
        {
            // 加载原始图片
            using (Image originalImage = Image.FromFile(inputPath))
            {
                // 计算新的尺寸（宽度和高度都缩小 scaleFactor 倍）
                int newWidth = originalImage.Width / scaleFactor;
                int newHeight = originalImage.Height / scaleFactor;

                Bitmap bitmap = new Bitmap(newWidth,newHeight);

                // 创建新的 Bitmap 对象
                using (Bitmap resizedImage = new Bitmap(newWidth, newHeight))
                {
                    // 配置 Graphics 对象以高质量缩放
                    using (Graphics graphics = Graphics.FromImage(resizedImage))
                    {
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;
                        graphics.DrawImage(originalImage, 0, 0, newWidth, newHeight);
                    }

                    //bitmap = resizedImage.Clone(new Rectangle(0,0,resizedImage.Width,resizedImage.Height), originalImage.PixelFormat);
                    //bitmap.Palette = originalImage.Palette;

                    bitmap = ConvertTo8bpp(resizedImage);

                    // 保存处理后的图片（保留原始格式）
                    resizedImage.Save(outputPath, originalImage.RawFormat);
                }
                bitmap.Save("pixtest.bmp");
                Console.WriteLine(bitmap.Size);
                ImageHandleV2(bitmap);

            }
        }

        public static Bitmap ScaleImage(Bitmap source, float scaleFactor)
        {
            // 创建目标位图
            int newWidth = (int)(source.Width * scaleFactor);
            int newHeight = (int)(source.Height * scaleFactor);
            var dest = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);

            // 锁定位图数据
            var sourceData = source.LockBits(
                new Rectangle(0, 0, source.Width, source.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);

            var destData = dest.LockBits(
                new Rectangle(0, 0, dest.Width, dest.Height),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb);

            try
            {
                // 创建字节数组保存像素数据
                int sourceBytes = Math.Abs(sourceData.Stride) * source.Height;
                byte[] sourcePixels = new byte[sourceBytes];
                Marshal.Copy(sourceData.Scan0, sourcePixels, 0, sourceBytes);

                int destBytes = Math.Abs(destData.Stride) * dest.Height;
                byte[] destPixels = new byte[destBytes];

                //// 处理每个目标像素
                for (int y = 0; y < newHeight; y++)
                {
                    int sourceY = (int)(y / scaleFactor);
                    sourceY = Math.Min(sourceY, source.Height - 1);

                    for (int x = 0; x < newWidth; x++)
                    {
                        int sourceX = (int)(x / scaleFactor);
                        sourceX = Math.Min(sourceX, source.Width - 1);

                        // 计算字节位置（32bpp = 4 bytes per pixel）
                        int sourceIndex = sourceY * sourceData.Stride + sourceX * 4;
                        int destIndex = y * destData.Stride + x * 4;

                        // 复制像素数据（BGRA格式）
                        destPixels[destIndex] = sourcePixels[sourceIndex];         // B
                        destPixels[destIndex + 1] = sourcePixels[sourceIndex + 1]; // G
                        destPixels[destIndex + 2] = sourcePixels[sourceIndex + 2]; // R
                        destPixels[destIndex + 3] = sourcePixels[sourceIndex + 3]; // A
                    }
                }

                // （替换上述算法部分）
                //for (int y = 0; y < newHeight; y++)
                //{
                //    float srcY = y / scaleFactor;
                //    int y1 = (int)srcY;
                //    int y2 = Math.Min(y1 + 1, source.Height - 1);
                //    float dy = srcY - y1;

                //    for (int x = 0; x < newWidth; x++)
                //    {
                //        float srcX = x / scaleFactor;
                //        int x1 = (int)srcX;
                //        int x2 = Math.Min(x1 + 1, source.Width - 1);
                //        float dx = srcX - x1;

                //        // 获取四个相邻像素
                //        byte[] p11 = GetPixel(sourcePixels, sourceData.Stride, x1, y1);
                //        byte[] p12 = GetPixel(sourcePixels, sourceData.Stride, x1, y2);
                //        byte[] p21 = GetPixel(sourcePixels, sourceData.Stride, x2, y1);
                //        byte[] p22 = GetPixel(sourcePixels, sourceData.Stride, x2, y2);

                //        // 插值计算
                //        byte[] result = new byte [4];
                //        for (int i = 0; i < 4; i++)
                //        {
                //            float val =
                //                p11[i] * (1 - dx) * (1 - dy) +
                //                p21[i] * dx * (1 - dy) +
                //                p12[i] * (1 - dx) * dy +
                //                p22[i] * dx * dy;

                //            result[i] = (byte)Math.Round(val);
                //        }

                //        // 写入目标像素
                //        int destIndex = y * destData.Stride + x * 4;
                //        Array.Copy(result, 0, destPixels, destIndex, 4);
                //    }
                //}




                Marshal.Copy(destPixels, 0, destData.Scan0, destBytes);
            }
            finally
            {
                source.UnlockBits(sourceData);
                dest.UnlockBits(destData);
            }
            dest.Save("BitmapTemp.bmp");
            return dest;
        }
        // 辅助方法
        public static  byte[] GetPixel(byte[] pixels, int stride, int x, int y)
        {
            int index = y * stride + x * 4;
            return new byte[] { pixels[index], pixels[index + 1], pixels[index + 2], pixels[index + 3] };
        }

        public static void ProcessImage(string inputPath, string outputPath)
        {
            // 加载原始图像
            using (Bitmap original = new Bitmap(inputPath))
            {
                // 验证图像格式
                if (original.PixelFormat != PixelFormat.Format8bppIndexed)
                {
                    throw new ArgumentException("输入图像必须为8bpp索引格式");
                }

                // 计算新尺寸（四分之一大小）
                int newWidth = original.Width / 4;
                int newHeight = original.Height / 4;

                // 创建目标位图（使用24位色深以获得更好的缩放质量）
                using (Bitmap resized = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb))
                {
                    // 保持原始分辨率
                    resized.SetResolution(original.HorizontalResolution, original.VerticalResolution);

                    // 创建高质量绘图表面
                    using (Graphics g = Graphics.FromImage(resized))
                    {
                        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        g.SmoothingMode = SmoothingMode.HighQuality;
                        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        g.CompositingQuality = CompositingQuality.HighQuality;

                        // 定义源区域和目标区域
                        Rectangle destRect = new Rectangle(0, 0, newWidth, newHeight);
                        Rectangle srcRect = new Rectangle(0, 0, original.Width, original.Height);

                        // 使用图像属性处理调色板转换
                        using (ImageAttributes attributes = new ImageAttributes())
                        {
                            // 禁用伽马校正
                            attributes.SetGamma(1.0f);
                            // 使用W4色差补偿
                            attributes.SetColorMatrix(new ColorMatrix(), ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                            // 执行高质量缩放
                            g.DrawImage(
                                original,
                                destRect,
                                srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height,
                                GraphicsUnit.Pixel,
                                attributes);
                        }
                    }

                    // 保存结果（推荐使用无损格式）
                    resized.Save(outputPath, ImageFormat.Png);
                }
            }
        }

        public static Bitmap ConvertTo8bpp(Bitmap original)
        {
            // 创建目标 8bpp 位图
            Bitmap target = new Bitmap(
                original.Width,
                original.Height,
                PixelFormat.Format8bppIndexed
            );

            // 设置灰度调色板（典型 8bpp 调色板）
            ColorPalette palette = target.Palette;
            for (int i = 0; i < 256; i++)
            {
                palette.Entries[i] = Color.FromArgb(i, i, i);
            }
            target.Palette = palette;

            // 锁定位图数据
            BitmapData originalData = original.LockBits(
                new Rectangle(0, 0, original.Width, original.Height),
                ImageLockMode.ReadOnly,
                original.PixelFormat
            );

            BitmapData targetData = target.LockBits(
                new Rectangle(0, 0, target.Width, target.Height),
                ImageLockMode.WriteOnly,
                target.PixelFormat
            );

            try
            {
                // 手动转换像素（简单亮度公式）
                unsafe
                {
                    byte* targetPtr = (byte*)targetData.Scan0;
                    int* originalPtr = (int*)originalData.Scan0;

                    for (int i = 0; i < original.Height; i++)
                    {
                        for (int j = 0; j < original.Width; j++)
                        {
                            int pixel = originalPtr[j];
                            // 亮度公式：0.299*R + 0.587*G + 0.114*B
                            byte brightness = (byte)(
                                (pixel & 0xFF) * 0.114 +         // B
                                ((pixel >> 8) & 0xFF) * 0.587 +  // G
                                ((pixel >> 16) & 0xFF) * 0.299   // R
                            );
                            targetPtr[j] = brightness;
                        }
                        targetPtr += targetData.Stride;
                        originalPtr += originalData.Stride / 4;
                    }
                }
            }
            finally
            {
                original.UnlockBits(originalData);
                target.UnlockBits(targetData);
            }

            return target;
        }


        public static Image CropImage(string inputPath, string outputPath, Rectangle cropArea)
        {
            // 加载原始图片
            using (var originalImage = new Bitmap(inputPath))
            {
                // 检查裁剪区域是否有效
                if (cropArea.X < 0 || cropArea.Y < 0 ||
                    cropArea.Width <= 0 || cropArea.Height <= 0 ||
                    cropArea.Right > originalImage.Width ||
                    cropArea.Bottom > originalImage.Height)
                {
                    throw new ArgumentException("Invalid crop area");
                }

                // 创建目标位图
                using (var croppedImage = new Bitmap(cropArea.Width, cropArea.Height))
                {
                    // 创建绘图对象
                    using (var graphics = Graphics.FromImage(croppedImage))
                    {
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.CompositingQuality = CompositingQuality.HighQuality;
                        // 绘制裁剪区域
                        graphics.DrawImage(
                            originalImage,
                            new Rectangle(0, 0, croppedImage.Width, croppedImage.Height),
                            cropArea,
                            GraphicsUnit.Pixel
                        );
                    }
                    Bitmap bitmap = new Bitmap(croppedImage);
                    bitmap = ConvertTo8bpp(bitmap);

                    ImageHandleV2_Scale4_Local(bitmap,"First13.bmp",2);

                    
                    //bitmap.Save(outputPath, originalImage.RawFormat);
                    // 保存图片
                    //croppedImage.Save(outputPath, originalImage.RawFormat);

                    return RectPoints(originalImage, convertList);
                }
            }
        }


        public static void ProcessImage(string imagePath, Rectangle cropArea, Point[] croppedPoints)
        {
            // 1. 加载原图
            using (Bitmap originalBitmap = new Bitmap(imagePath))
            {
                // 2. 截取指定区域
                Bitmap croppedBitmap = CropImage(originalBitmap, cropArea);

                // 3. 在截取图上绘制线框（演示用）
                //DrawPolygonOnImage(croppedBitmap, croppedPoints, Pens.Red);

                // 4. 转换坐标到原图
                Point[] originalPoints = ConvertPointsToOriginal(croppedPoints, cropArea);

                // 5. 在原图上绘制线框
                //DrawPolygonOnImage(originalBitmap, originalPoints, Pens.Blue);

                // 6. 保存结果
                originalBitmap.Save("RectOutput.jpg", ImageFormat.Jpeg);
                croppedBitmap.Save("RectCropped.jpg", ImageFormat.Jpeg);
            }
        }

        public static Bitmap CropImage(Bitmap source, Rectangle cropArea)
        {
            Bitmap target = new Bitmap(cropArea.Width, cropArea.Height);
            using (Graphics g = Graphics.FromImage(target))
            {
                g.DrawImage(source, new Rectangle(0, 0, target.Width, target.Height),
                            cropArea, GraphicsUnit.Pixel);
            }
            return target;
        }

        public static void DrawPolygonOnImage(Bitmap image, Point[] points, Pen pen)
        {
            using (Graphics g = Graphics.FromImage(image))
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                g.DrawPolygon(pen, points);
            }
        }

        public static Point[] ConvertPointsToOriginal(Point[] croppedPoints, Rectangle cropArea)
        {
            Point[] points= croppedPoints.Select(p => new Point(
                 p.X + cropArea.X,
                 p.Y + cropArea.Y
             )).ToArray();
            foreach (var item in points)
            {
                //Console.WriteLine("Convert: "+"x;"+item.X+"   "+"y:" + item.Y);
            }
            return points;
    
        }

        public static List<List<Point>> ConvertPointList(List<List<Point>> pointList, Rectangle cropArea)
        {
            List<List<Point>> tempList = new List<List<Point>>();
            for (int i = 0; i < pointList.Count; i++)
            {
                tempList.Add(ConvertPointsToOriginal(pointList[i].ToArray(), cropArea).ToList());
            }

            return tempList;
        }

    }
}
